package com.lenovo.study.service.impl;

import com.lenovo.study.service.DistributedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Author: fuxh3@lenovo.com
 * Date: Created in 2017/9/5 0005
 */
@Service public class RedisDistributedLock implements DistributedLock {
    @Autowired private JedisPool jedisPool;
    private static final String LOCK_NAME = "LOCK";
    private ThreadLocal<String> local = new ThreadLocal<>();
    @Override public Boolean getLock() {
        Jedis jedis = jedisPool.getResource();
        String value = UUID.randomUUID().toString();
        String ret = jedis.set(LOCK_NAME,value,"NX","PX",10000);
        if(!StringUtils.isEmpty(ret) && ret.equals("OK")){
            local.set(value);
            jedis.close();
            return true;
        }
        jedis.close();
        return false;
    }

    @Override public void releaseLock() {
        String script = null;
        Jedis jedis = null;
        try {
            script = FileCopyUtils.copyToString(new FileReader(ResourceUtils.getFile("classpath:unlock.lua")));
            jedis = jedisPool.getResource();
            List<String> keys = new ArrayList<>();
            keys.add(LOCK_NAME);
            List<String> args = new ArrayList<>();
            args.add(local.get());
            jedis.eval(script,keys,args);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(jedis!=null){
                jedis.close();
            }
        }
    }
}
